package com.bigfans.cartservice.api;

import com.bigfans.cartservice.model.Cart;
import com.bigfans.cartservice.model.CartItem;
import com.bigfans.cartservice.model.Product;
import com.bigfans.cartservice.model.ProductSpec;
import com.bigfans.cartservice.service.CartService;
import com.bigfans.cartservice.service.ProductService;
import com.bigfans.cartservice.service.ProductSpecService;
import com.bigfans.cartservice.service.impl.RedisService;
import com.bigfans.framework.Applications;
import com.bigfans.framework.CurrentUser;
import com.bigfans.framework.annotations.NeedLogin;
import com.bigfans.framework.exception.ServiceRuntimeException;
import com.bigfans.framework.utils.CollectionUtils;
import com.bigfans.framework.web.BaseController;
import com.bigfans.framework.web.RestResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class CartController extends BaseController {

    @Autowired
    private CartService cartService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private ProductService productService;
    @Autowired
    private ProductSpecService productSpecService;

    @GetMapping(value = "/mycart")
    public RestResponse mycart() throws Exception {
        Cart cart = null;
        CurrentUser cu = Applications.getCurrentUser();
        if (cu.isLoggedIn()) {
            cart = cartService.myCart(cu.getUid());
        } else {
            List<CartItem> cartItems = redisService.getCartItems(cu.getUid());
            cart = cartService.populateCart(cartItems);
        }
        return RestResponse.ok(cart);
    }

    @GetMapping(value = "/minicart")
    public RestResponse cartSummary() throws Exception {
        Cart cart = null;
        CurrentUser cu = Applications.getCurrentUser();
        if (cu.isLoggedIn()) {
            cart = cartService.cartSummary(cu.getUid(), 5L);
        } else {
            cart = redisService.cartSummary(cu.getUid(), 5);
            if (cart != null) {
                List<CartItem> items = cart.getItems();
                if (CollectionUtils.isNotEmpty(items)) {
                    for (CartItem cartItem : items) {
                        Product p = productService.load(cartItem.getProdId());
                        cartItem.setPrice(p.getPrice());
                        cartItem.setProdName(p.getName());
                        cartItem.setProdImg(p.getImagePath());
                    }
                }
            }
        }
        RestResponse response = new RestResponse();
        response.setData(cart == null ? new Cart() : cart);
        return response;
    }

    @PostMapping(value = "/addItem")
    // 后台使用@RequestBody接收时候前台传递参数必须是json字符串而不是json对象
    public RestResponse addItem(@RequestBody CartItem newItem)
            throws Exception {
        CurrentUser cu = Applications.getCurrentUser();
        if (cu.isLoggedIn()) {
            cartService.addItem(cu.getUid(), newItem.getProdId(), newItem.getQuantity());
        } else {
            redisService.addItem(cu.getUid(), newItem.getProdId(), newItem.getQuantity());
        }
        return RestResponse.ok();
    }

    @PostMapping(value = "/removeItem")
    public RestResponse remove(@RequestParam(name = "prodId") String prodId, @RequestParam(name = "id") String id)
            throws Exception {
        CurrentUser cu = Applications.getCurrentUser();
        Cart cart = null;
        if (cu.isLoggedIn()) {
            cartService.removeItem(cu.getUid(), id);
            cart = cartService.myCart(cu.getUid(), null, null);
        } else {
            redisService.removeCartItem(cu.getUid(), prodId);
            List<CartItem> cartItems = redisService.getCartItems(cu.getUid());
            cart = cartService.populateCart(cartItems);
        }
        return RestResponse.ok(cart);
    }

    @GetMapping(value = "/clear")
    public RestResponse clear() throws Exception {
        CurrentUser cu = Applications.getCurrentUser();
        if (cu.isLoggedIn()) {
            cartService.removeCart(cu.getUid());
        } else {
            redisService.removeCart(cu.getUid());
        }
        return RestResponse.ok();
    }

    @PostMapping(value = "/changeQuantity")
    public RestResponse changeQuantity(
            @RequestParam(name = "prodId") String prodId,
            @RequestParam(name = "quantity") Integer quantity
    ) throws Exception {
        CurrentUser cu = Applications.getCurrentUser();
        if (cu.isLoggedIn()) {
            try {
                cartService.updateQuantity(cu.getUid(), prodId, quantity);
            } catch (ServiceRuntimeException e) {
                RestResponse.error(e.getErrorCode(), e.getMessage());
            }
        } else {
            redisService.updateAmount(cu.getUid(), prodId, quantity);
        }
        Cart cart = cartService.myCart(cu.getUid());
        return RestResponse.ok(cart);
    }

    /**
     * 勾选商品
     *
     * @param prodId
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/selectItem")
    public RestResponse selectItem(@RequestParam(name = "prodId") String prodId) throws Exception {
        CurrentUser cu = Applications.getCurrentUser();
        if (cu.isLoggedIn()) {
            cartService.select(cu.getUid(), prodId);
        } else {
            redisService.selectCartItem(cu.getUid(), prodId);
        }
        Cart cart = cartService.myCart(cu.getUid());
        return RestResponse.ok(cart);
    }

    /**
     * 勾选商品
     *
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/selectAllItems")
    public RestResponse selectAllItems() throws Exception {
        CurrentUser cu = Applications.getCurrentUser();
        if (cu.isLoggedIn()) {
            cartService.selectAll(cu.getUid());
        } else {
            redisService.selectAllCartItems(cu.getUid());
        }
        Cart cart = cartService.myCart(cu.getUid());
        return RestResponse.ok(cart);
    }

    /**
     * 取消勾选的商品
     *
     * @param prodId
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/cancelItem")
    public RestResponse cancelItem(@RequestParam(name = "prodId") String prodId) throws Exception {
        CurrentUser cu = Applications.getCurrentUser();
        if (cu.isLoggedIn()) {
            cartService.cancel(cu.getUid(), prodId);
        } else {
            redisService.cancelCartItem(cu.getUid(), prodId);
        }
        Cart cart = cartService.myCart(cu.getUid());
        return RestResponse.ok(cart);
    }

    /**
     * 取消勾选的商品
     *
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/cancelAllItems")
    public RestResponse cancelAllItems() throws Exception {
        CurrentUser cu = Applications.getCurrentUser();
        if (cu.isLoggedIn()) {
            cartService.cancelAll(cu.getUid());
        } else {
            redisService.cancelAllCartItems(cu.getUid());
        }
        Cart cart = cartService.myCart(cu.getUid());
        return RestResponse.ok(cart);
    }

    @GetMapping(value = "/checkoutItems")
    @NeedLogin
    public RestResponse checkoutItems() throws Exception {
        CurrentUser cu = Applications.getCurrentUser();
        List<CartItem> selectedItems = cartService.getSelectedItems(cu.getUid());
        for(CartItem cartItem : selectedItems){
            List<ProductSpec> specList = productSpecService.listProductSpecs(cartItem.getProdId());
            cartItem.setSpecList(specList);
        }
        return RestResponse.ok(selectedItems);
    }
}